package com.eva.databuilder.builders;

import cn.hutool.core.util.ObjectUtil;
import com.eva.databuilder.bo.TemplateDataParameters;
import com.eva.databuilder.bo.TemplatePresetDataList;
import com.eva.framework.cache.CacheProxy;
import com.eva.framework.config.AppConfig;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 模板数据构建器，所有数据构建器均继承该类
 */
@Slf4j
public abstract class AbstractTemplateDataBuilder<T> {

    private static AppConfig appConfig;

    private static CacheProxy<String, Object> cacheProxy;

    /**
     * 构建数据
     *
     * @param parameters 构建数据参数
     * @return T
     */
    public abstract T build (TemplateDataParameters parameters);

    /**
     * 构建数据
     *
     * @param presetDataList 预设数据
     * @return Map<String, Object>
     */
    public static Map<String, Object> build (TemplatePresetDataList presetDataList) {
        Map<String, Object> data = new HashMap<>();
        while(presetDataList.hasNext()) {
            TemplatePresetDataList.TemplatePresetData presetData = presetDataList.next();
            // 回写构建器参数
            data.put(presetData.getCode() + "_PARAMETERS", presetData.getParameters());
            // 构建数据
            if (presetData.getBuilder() == null) {
                log.warn("数据构建器 " + presetData.getCode() + " 未实现，已跳过构建！");
                continue;
            }
            // - 启用了缓存，则从缓存中读取
            if (presetData.getEnabledCache()) {
                Object result = cacheProxy.get(presetData.getCode());
                if (result != null) {
                    data.put(presetData.getCode(), result);
                    continue;
                }
            }
            // - 未启用缓存或缓存中没有数据，则使用构建器构建
            Object result = presetData.getBuilder().build(presetData.getParameters());
            if (presetData.getEnabledCache() && !ObjectUtil.isEmpty(result)) {
                cacheProxy.put(presetData.getCode(), result, appConfig.getTemplateDataCacheExpire());
            }
            data.put(presetData.getCode(), result);
        }
        return data;
    }

    @Resource
    public void setAppConfig (AppConfig appConfig) {
        AbstractTemplateDataBuilder.appConfig = appConfig;
    }

    @Resource
    public void setCacheProxy (CacheProxy<String, Object> cacheProxy) {
        AbstractTemplateDataBuilder.cacheProxy = cacheProxy;
    }
}
